<?
define("ERR_MYSQL_CONN_FAIL",	501);		// 연결 실패
define("ERR_MYSQL_SELECTDB_FAIL", 502);		// mysql_select_db 실패
define("ERR_MYSQL_NOT_CONNECTED", 503);		// 접속안되었음
define("ERR_MYSQL_QUERY_FAIL",	510);		// 질의 실패
define("ERR_MYSQL_SYNTAX_ERR",	510.1);		// SQL문 문법오류
define("ERR_MYSQL_UNKNOWN_COL", 510.2);		// 알 수없는 필드명
define("ERR_MYSQL_UNKNOWN_TAB", 510.3);		// 알 수없는 테이블
define("ERR_MYSQL_NOT_NULL",	510.4);		// NULL 허용 안됨
define("ERR_MYSQL_DUP_KEY",		510.5);		// KEY 중복
define("ERR_MYSQL_NOAUTH",		510.6);		// 권한부족

class Page
{
	var $page;
	var $total_count;
	var $page_size;
	var $total_page;

	function printPageList($pagelistsize, $href_base, $options)
	{
		DefaultPrintPageList($this, $pagelistsize, $href_base, $options);
	}
}

function DefaultPrintPageList($pageObj, $pagelistsize, $href_base, $options)
{
}

class SQLRow
{
	// mysql_fetch_array() 의 리턴값과 같은 형식
	// 단 숫자 인덱스는 지원하지 않음
	// private Array row_array;
	var $row_array;

	function SQLRow(&$row_array)
	{
		$this->row_array =& $row_array;
	}

	// String getString(String name [, String defaultValue ] );
	function getString($name, $defaultValue = "")
	{
		return $this->row_array[$name];
	}

	// Number getNumber(String name [, Number defaultValue ] );
	function getNumber($name, $defaultValue = 0)
	{
		return $this->row_array[$name] + 0;
	}

	// boolean getBoolean(String name [, boolean defaultValue ] );
	function getBoolean($name, $defaultValue = false)
	{
		$value = $this->row_array[$name];
		if (strtolower($value) == "n")
			return false;
		elseif (strtolower($value) == "no")
			return false;
		elseif (strtolower($value) == "false")
			return false;
		// javascript의 특성상 이런 형태로 전달될 수 있음
		elseif (strtolower($value) == "null")
			return false;
		// javascript의 특성상 이런 형태로 전달될 수 있음
		elseif (strtolower($value) == "undefined")
			return false;
		elseif (strtolower($value) == "아니오")
			return false;
		else
			return (bool)$value;
	}
}

class SQLList
{
	var $rs;
	var $lenth;
	var $index;

	function SQLList($rs)
	{
		$this->rs = $rs;
		$this->length = @mysql_num_rows($rs);
		$this->index = 0;
	}

	// SQLRow next();
	function &next()
	{
		if ($this->rs)
		{
			$this->index++;
			$array = @mysql_fetch_array($this->rs);
			$row = new SQLRow($array);

			// 순회가 1회 끝나면 자동으로 close()되게 함
			//if (!$this->hasNext())
			//	$this->close();

			return $row;
		}
		else
			return null;
	}

	// boolean hasNext();
	// 행이 더 남아있으면 참 아니면 거짓
	function hasNext()
	{
		if ($this->rs)
			return ($this->length > $this->index);
		else
			return false;
	}

	// int getLength();
	function getLength()
	{
		return $this->length;
	}

	// int getCurrentIndex();
	function getCurrentIndex()
	{
		return $this->index;
	}

	// void close();
	function close()
	{
		if ($this->rs)
		{
			@mysql_free_result($this->rs);
			unset($this->rs);
		}
	}
}

/*
	$db = new MySQLConnection();
	$db->connect();
	$rs =& $db->query($sql);		// mysql_query() 와 동일
	$row =& $db->queryRow($sql);	// SQLRow를 리턴
	$list =& $db->queryList($sql);	// SQLList를 리턴
*/
class MySQLConnection
{
	var $db;
	var $in_trasaction;

	// constructor
	function MySQLConnection($db = null)
	{
		if ($db != null)
			$this->db = $db;
		$this->in_trasaction = false;
	}

	// PHP >= 4.2.0
	// PHP 4.2 이상의 경우 디폴트로 한페이지에 하나씩의 커넥션을 유지한다.
	// 연결을 시도할 때 이미 열려진 커넥션이 있으면 새로 연결하지 않는다.
	function connect($dbserver = null, $dbuser = null, $dbpass = null, $database = null)
	{
		global $DEFAULT_DBSERVER, $DEFAULT_DBUSER, $DEFAULT_DBPASS, $DEFAULT_DATABASE, $MYSQL_OPENED_CONNECTIONS;
		if ($dbserver == null) $dbserver = $DEFAULT_DBSERVER;
		if ($dbuser == null) $dbuser = $DEFAULT_DBUSER;
		if ($dbpass == null) $dbpass = $DEFAULT_DBPASS;
		if ($database == null) $database = $DEFAULT_DATABASE;

		if (get_cfg_var("mysql.allow_persistent") == 1)
		{
			if ($dbserver == null || $dbuser == null)
				$db = @mysql_pconnect();
			else
			{
				$db = @mysql_connect($dbserver, $dbuser, $dbpass);
			}

			// 연결되어 대기하던 커넥션일 수 있으므로,  연결을 확인한다.
			if ($db && !@mysql_ping($db))
				$db = null;
		}
		else
		{
			if ($dbserver == null || $dbuser == null)
				$db = @mysql_connect();
			else
				$db = @mysql_connect($dbserver, $dbuser, $dbpass);
		}

		if (!$db)
		{
			raise_error(ERR_MYSQL_CONN_FAIL);
			return false;
		}

		// 데이터베이스가 지정되었는데도
		// DB 선택이 실패하면 연결실패한 것으로 간주한다.
		if ($database)
		{
			if (!@mysql_select_db($database, $db))
			{
				//echo mysql_error();
				@mysql_close($db);
				raise_error(ERR_MYSQL_SELECTDB_FAIL);
				return false;
			}
		}

		// 페이지 종료시에 자동으로 close되도록 등록
		// PHP는 destructor가 없기 때문에 이런 식으로 처리
		// 그러나 MySQL의 경우 페이지 종료시 PHP가 닫아주기 때문에 필요없다.
		if (!is_array($MYSQL_OPENED_CONNECTIONS))
			$MYSQL_OPENED_CONNECTIONS = array();
		if (!in_array($db, $MYSQL_OPENED_CONNECTIONS))
		{
			array_push($MYSQL_OPENED_CONNECTIONS, $db);
		}
		
		mysql_query("SET NAMES utf8");
		
		$this->db = $db;
		return true;
	}
	
	function select_db($database = null)
	{
		global $DEFAULT_DATABASE;

		if ($database == null)
			$database = $DEFAULT_DATABASE;
		if ($this->db && $database)
		{
			if (!@mysql_select_db($database, $this->db))
			{
				//echo mysql_error();
				@mysql_close($db);
				raise_error(ERR_MYSQL_SELECTDB_FAIL);
				return false;
			}
			else
				return true;
		}
		else
			return false;
	}

	// void close();
	function close()
	{
		if ($this->db)
		{
			@mysql_close($this->db);
			unset($this->db);
		}
	}

	function &query($sql)
	{
		if (!$this->db)
			raise_error(ERR_MYSQL_NOT_CONNECTED);

		$rs = @mysql_query($sql, $this->db);
		if (!$rs)
		{
			$errno = mysql_errno();
			if ($errno == 1064)				// syntax error
				raise_error(ERR_MYSQL_SYNTAX_ERR);
			elseif ($errno == 1054)			// unknown column
				raise_error(ERR_MYSQL_UNKNOWN_COL);
			elseif ($errno == 1146)			// unknown table
				raise_error(ERR_MYSQL_UNKNOWN_TAB);
			elseif ($errno == 1048)			// NOT NULL
				raise_error(ERR_MYSQL_NOT_NULL);
			elseif ($errno == 1062)			// Key 중복
				raise_error(ERR_MYSQL_DUP_KEY);
			elseif ($errno == 1044 || $errno == 1045)			// 권한부족
				raise_error(ERR_MYSQL_NOAUTH);
			else
				raise_error(ERR_MYSQL_QUERY_FAIL);
			return null;
		}
		else
			return $rs;
	}

	function &queryRow($sql)
	{
		$list =& $this->queryList($sql);
		if ($list->hasNext())
		{
			$row =& $list->next();
			
			//$row = _noHtmlArray(      & $list->next()       );
			
		}
		$list->close();
		return $row;
	}

	function &queryList($sql)
	{
		$rs = $this->query($sql);
		$list = new SQLList($rs);
		return $list;
	}

	function escape($str)
	{
		return $str;
	}
	
	function queryInsert($table, $array)
	{
		if (!is_array($array))
			return false;
		$columns = array_keys($array);
		$values = $array;
		
		//$values = _noInjection($values);
		
		$sql = "INSERT INTO $table (";
		$sql .= join(", ", $columns);
		$sql .= ") VALUES ('";
		$sql .= join("', '", $values);
		$sql .= "')";
		//echo $sql;
		return $this->query($sql);
	}

	function queryInsertWithId($table, $array, &$new_id)
	{
		if (!is_array($array))
			return false;
		$columns = array_keys($array);
		$values = array_values($array);
		
		//$values = _noInjection($values);
		
		$sql = "INSERT INTO $table (";
		$sql .= join(", ", $columns);
		$sql .= ") VALUES ('";
		$sql .= join("', '", $values);
		$sql .= "')";

		$result = $this->query($sql);
		if ($result)
		{
			$new_id = @mysql_insert_id($this->db);
			return true;
		}
		else
		{
			$new_id = 0;
			return false;
		}
	}

	function queryUpdate($table, $array, $where)
	{
		if (!is_array($array))
			return false;
		$columns = array_keys($array);
		$len = count($columns);
		$sql = "UPDATE $table SET ";
		for ($i = 0; $i < $len; $i++)
		{
			$column = $columns[$i];
			$value = $array[$column];
			
			//$value = mysql_real_escape_string($array[$column]);
			
			$sql .= " $column = '$value' ";
			if ($i < $len - 1)
				$sql .= ", ";
		}
		$sql .= " WHERE ($where)";
		return $this->query($sql);
	}

	function queryDelete($table, $where)
	{
		$sql = "DELETE FROM $table WHERE ($where)";
		return $this->query($sql);
	}
	
	function queryDelete2($table, $where)
	{
		$sql = "DELETE FROM $table WHERE $where";
		return $this->query($sql);
	}

	function insert_id()
	{
		return @mysql_insert_id($this->db);
	}

	function begin()
	{
		if (!$this->in_trasaction)
		{
			$this->query("BEGIN");
			$this->in_trasaction = 1;
		}
	}

	function commit()
	{
		if ($this->in_trasaction)
		{
			$this->query("COMMIT");
			$this->in_trasaction = 0;
		}
	}

	function rollback()
	{
		if ($this->in_trasaction)
		{
			$this->query("ROLLBACK");
			$this->in_trasaction = 0;
		}
	}
}

register_shutdown_function('MySQLCloseAllOpenedConnections');

function MySQLCloseAllOpenedConnections()
{
	if (is_array($MYSQL_OPENED_CONNECTIONS))
	{
		foreach ($MYSQL_OPENED_CONNECTIONS as $conn)
		{
			// 종료되지 않고 남아있는 모든 트랜잭션은 롤백된다.
			@mysql_query("ROLLBACK", $conn);
			@mysql_close($conn);
		}
	}
}
?>